﻿#include "MEMSDataCodec.h"

#include "DataPackage_UdpCodec.h"
#include "Mapper_MEMSData.h"
#include "MEMSData.h"

MEMSDataCodec::MEMSDataCodec()
{
setObjectName(getClassNameFirstLow<MEMSDataCodec>());
}

MEMSDataCodec::~MEMSDataCodec()
{
}

void MEMSDataCodec::slot_decode(QByteArray data) //拆解数据
{
  dataBuffer.append(data);
  decode();
}
void MEMSDataCodec::decode()
{
  while ((dataBuffer.size() / dataPackageSize) > 0)
    {
      int dataPackageType = -1, groupIndex = -1;
      if (checkDataPackageHead() && checkDataPackageGroupFlag(&dataPackageType, &groupIndex) && checkDataPackageCheckSummation(dataPackageType))
        {
          QByteArray data=dataBuffer.mid(2, 14);
          logSaver->saveLog("groupIndex:"+QString::number(groupIndex)+" data:"+data.toHex());
           if(!mapper_MEMSData->saveMEMSData(MEMSData(dataBuffer.mid(0, dataPackageSize))))//如果存储失败则再存一次
             {
               mapper_MEMSData->saveMEMSData(MEMSData(dataBuffer.mid(0, dataPackageSize)));//再失败就不管了
             }
          emit signal_feedbackData(groupIndex, data);//发送拆解后的数据
          dataBufferDropData(dataPackageSize);
        }
    }
}
bool MEMSDataCodec::checkDataPackageHead()
{
  if ((dataBuffer.at(0)&0xff) == (Head&0xff))
    {
      return true;
    }
  else
    {
      dataBufferDropData(1);
      return false;
    }
}
bool MEMSDataCodec::checkDataPackageGroupFlag()
{
  int dataPackageType, groupIndex;
  return checkDataPackageGroupFlag(&dataPackageType, &groupIndex);
}
bool MEMSDataCodec::checkDataPackageGroupFlag(int* dataPackageType, int* groupIndex)
{
  bool isValid = false;
  switch (dataBuffer.at(1)&0xff)
    {
    case (uchar)DataFlag::SingleData:
      if (this->dataPackagetype == Multi)
        {

          isValid = false;
          break;
        }
      *dataPackageType = 0;
      *groupIndex = 0;
      isValid = true;
      break;
    case (uchar)DataFlag::MultiData1:
      if (this->dataPackagetype == Single)
        {
          isValid = false;
          break;
        }
      *dataPackageType = 1;
      *groupIndex = 0;
      isValid = true;
      break;
    case (uchar)DataFlag::MultiData2:
      if (this->dataPackagetype == Single)
        {
          isValid = false;
          break;
        }
      *dataPackageType = 1;
      *groupIndex = 1;
      isValid = true;
      break;
    case (uchar)DataFlag::MultiData3:
      if (this->dataPackagetype == Single)
        {
          isValid = false;
          break;
        }
      *dataPackageType = 1;
      *groupIndex = 2;
      isValid = true;
      break;
    case (uchar)DataFlag::MultiData4:
      if (this->dataPackagetype == Single)
        {
          isValid = false;
          break;
        }
      *dataPackageType = 1;
      *groupIndex = 3;
      isValid = true;
      break;
    case (uchar)DataFlag::MultiData5:
      if (this->dataPackagetype == Single)
        {
          isValid = false;
          break;
        }
      *dataPackageType = 1;
      *groupIndex = 4;
      isValid = true;
      break;
    case (uchar)DataFlag::MultiData6:
      if (this->dataPackagetype == Single)
        {
          isValid = false;
          break;
        }
      *dataPackageType = 1;
      *groupIndex = 5;
      isValid = true;
      break;
    default:
      isValid = false;
      break;
    }
  if (!isValid)
    {
      dataBufferDropData(1);
      *dataPackageType = -1;
      *groupIndex = -1;
    }
  return isValid;
}
bool MEMSDataCodec::checkDataPackageCheckSummation(int dataPackageType)
{
  switch (dataPackageType)
    {
    case -1:
      return false;
    case 0:
      return checkCheckSummation(2, 15);
    case 1:
      return checkCheckSummation(0, 15);
    default:
      return false;
    }
}
void MEMSDataCodec::dataBufferDropData(int byteCount)
{
  dataBuffer.remove(0, byteCount);
}
void MEMSDataCodec::addCheckSummation(QByteArray* instruction)//为输入的bytearray添加检查和
{
  int len = 16/*instruction->size()*/;
  char total = 0;
  for (int i = 0; i < len; i++) {
      char temp = instruction->at(i);
      total += temp;
    }
  instruction->append(total);
  return;
}
short MEMSDataCodec::char2ToShort(uchar H8, uchar L8)//两char转short，解析数据时使用
{
  short data1 = 0;
  data1 = ((data1 | H8) << 8) | L8;
  return data1;
}
char* MEMSDataCodec::shortToChar2(short data, char* data1)//short转两char，编码数据时使用
{
  data1[0] = data >> 8;
  data1[1] = data;
  return data1;
}
bool MEMSDataCodec::checkCheckSummation(int begin, int end)//检查检查和，检查检查和,end代表结束位置的下标和begin代表开始位置的下标
{
  uchar total = 0;
  for (int i = begin; i <= end; i++)
    {
      total = bitSum(total&0xff, dataBuffer.at(i)&0xff)&0xff;
    }
  if (total == (dataBuffer.at(end + 1)&0xff))
    {
      return true;
    }
  else
    {
      dataBufferDropData(1);
      return false;
    }
}

char MEMSDataCodec::bitSum(char x, char y)
{
  if (x == 0)
    {
      return y;
    }
  if (y == 0)
    {
      return x;
    }
  return bitSum((x ^ y), ((x & y) << 1));
}

MEMSDataCodec::DataPackagetype MEMSDataCodec::getDataPackagetype()
{
  return dataPackagetype;
}
void MEMSDataCodec::setDataPackagetype(DataPackagetype dataPackagetype)
{
  this->dataPackagetype = dataPackagetype;
  emit signal_currentDataPackageype(dataPackagetype);
}

Mapper_MEMSData* MEMSDataCodec::getMapper_MEMSData() const
{
  return mapper_MEMSData;
}

void MEMSDataCodec::setMapper_MEMSData(Mapper_MEMSData* mapper_MEMSData)
{
  this->mapper_MEMSData=mapper_MEMSData;
  printInjection(this,mapper_MEMSData);
}

void MEMSDataCodec::objectAutoInjection(QHash<QString,QObject*>* objMap)
{
  setMapper_MEMSData(getObjFromMap<Mapper_MEMSData>(objMap));
  ObjAutoInject::objectAutoInjection(objMap);
}
